<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<title>No Title</title>
<style type="text/css">
body {
    margin: auto;
    font-family: Verdana, sans-serif;
    padding: 8px 1%;
}

a { color: #044a64 }
a:visited { color: #734559 }

.logo { position:absolute; margin:3px; }
.tagline {
  float:right;
  text-align:right;
  font-style:italic;
  width:300px;
  margin:12px;
  margin-top:58px;
}

.toolbar {
  text-align: center;
  line-height: 1.6em;
  margin: 0;
  padding: 0px 8px;
}
.toolbar a { color: white; text-decoration: none; padding: 6px 12px; }
.toolbar a:visited { color: white; }
.toolbar a:hover { color: #044a64; background: white; }

.content    { margin: 5%; }
.content dt { font-weight:bold; }
.content dd { margin-bottom: 25px; margin-left:20%; }
.content ul { padding:0px; padding-left: 15px; margin:0px; }

/* rounded corners */
.se  { background: url(images/se.gif) 100% 100% no-repeat #044a64}
.sw  { background: url(images/sw.gif) 0% 100% no-repeat }
.ne  { background: url(images/ne.gif) 100% 0% no-repeat }
.nw  { background: url(images/nw.gif) 0% 0% no-repeat }

/* Things for "fancyformat" documents start here. */
.fancy img+p {font-style:italic}
.fancy .codeblock i { color: darkblue; }
.fancy h1,.fancy h2,.fancy h3,.fancy h4 {font-weight:normal;color:#044a64}
.fancy h2 { margin-left: 10px }
.fancy h3 { margin-left: 20px }
.fancy h4 { margin-left: 30px }
.fancy th {white-space:nowrap;text-align:left;border-bottom:solid 1px #444}
.fancy th, .fancy td {padding: 0.2em 1ex; vertical-align:top}
.fancy #toc a        { color: darkblue ; text-decoration: none }
.fancy .todo         { color: #AA3333 ; font-style : italic }
.fancy .todo:before  { content: 'TODO:' }
.fancy p.todo        { border: solid #AA3333 1px; padding: 1ex }
.fancy img { display:block; }
.fancy :link:hover, .fancy :visited:hover { background: wheat }
.fancy p,.fancy ul,.fancy ol { margin: 1em 5ex }
.fancy li p { margin: 1em 0 }
/* End of "fancyformat" specific rules. */

</style>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
  
</head>
<body>
<div><!-- container div to satisfy validator -->

<a href="index.html">
<img class="logo" src="images/sqlite370_banner.gif" alt="SQLite Logo"
 border="0"></a>
<div><!-- IE hack to prevent disappearing logo--></div>
<div class="tagline">Small. Fast. Reliable.<br>Choose any three.</div>

<table width=100% style="clear:both"><tr><td>
  <div class="se"><div class="sw"><div class="ne"><div class="nw">
  <table width=100% style="padding:0;margin:0;cell-spacing:0"><tr>
  <td width=100%>
  <div class="toolbar">
    <a href="about.html">About</a>
    <a href="sitemap.html">Sitemap</a>
    <a href="docs.html">Documentation</a>
    <a href="download.html">Download</a>
    <a href="copyright.html">License</a>
    <a href="news.html">News</a>
    <a href="support.html">Support</a>
  </div>
<script>
  gMsg = "Search SQLite Docs..."
  function entersearch() {
    var q = document.getElementById("q");
    if( q.value == gMsg ) { q.value = "" }
    q.style.color = "black"
    q.style.fontStyle = "normal"
  }
  function leavesearch() {
    var q = document.getElementById("q");
    if( q.value == "" ) { 
      q.value = gMsg
      q.style.color = "#044a64"
      q.style.fontStyle = "italic"
    }
  }
</script>
<td>
    <div style="padding:0 1em 0px 0;white-space:nowrap">
    <form name=f method="GET" action="http://www.sqlite.org/search">
      <input id=q name=q type=text
       onfocus="entersearch()" onblur="leavesearch()" style="width:24ex;padding:1px 1ex; border:solid white 1px; font-size:0.9em ; font-style:italic;color:#044a64;" value="Search SQLite Docs...">
      <input type=submit value="Go" style="border:solid white 1px;background-color:#044a64;color:white;font-size:0.9em;padding:0 1ex">
    </form>
    </div>
  </table>
</div></div></div></div>
</td></tr></table>
<div class=startsearch></div>
  

<div class=fancy>

<h1>Test Plan for FTS3</h1>

Terms:
<ol>
  <li> basic query.
  <li> composite query.
  <li> matchable phrase.
  <li> phrase match.
</ol>

<h2>Query Parsing Details</h2>

<h2>Query Matching Details</h2>

<h3>Basic Query Matching</h3>
<p>
  A basic query consists of one or more phrases joined together by NEAR 
  operators. Each phrase consists of an ordered list of one or more terms 
  or term prefixes.

<p>
  Evaluating a basic query against a row of an FTS3 table produces two 
  outputs: a Boolean value (the result of the basic query expression) and zero
  or more phrase matches (used by the auxillary functions). A phrase match is a
  series of zero or more tokens within the row data that match a specific
  phrase within the basic query, and meet the 'nearness' constraints placed
  on the phrase by the NEAR operators to the left and right of it in the
  basic query (if any).

<ul>
  <li><p> A contiguous set of tokens within a single column of the current
       row shall be considered a phrase match for a given phrase within the
       basic query if all of the following conditions are met:
    <ol>
      <li><p> Either the phrase does not have an associated column, or the
       contiguous set of tokens appears within the table column associated
       with the phrase in the basic query expression.

      <li><p> The number of tokens in the contiguous set is the same as the 
       number of terms and term prefixes in the phrase.

      <li><p> Each token in the contiguous set that corresponds to a term (not
       a term prefix) in the phrase is an exact match for the term.

      <li><p> Each token in the contiguous set that corresponds to a term prefix
       (not an ordinary term) in the phrase consists of an exact match for
       the term prefix followed by zero or more additional characters.

      <li><p> The phrase is either the leftmost in the basic query, or there
       exists a phrase match corresponding to the phrase to the left of this 
       one with not more than <i>N</i> document tokens between it and this 
       phrase match, where <i>N</i> is the parameter given to the NEAR 
       operator separating the two phrases in the basic query expression.

      <li><p> The phrase is either the rightmost in the basic query, or there 
       exists a phrase match corresponding to the phrase to the right of this 
       one with not more than <i>N</i> document tokens between it and this 
       phrase match, where <i>N</i> is the parameter given to the NEAR 
       operator separating the two phrases in the basic query expression.
    </ol>
</ul>

<ul>
  <li><p> The result of evaluating a basic query expression shall be true if
       the current row contains one or more phrase matches corresponding to
       phrases within the basic query.

  <li><p> The result of evaluating a basic query expression shall be false if
       the current row contains one or more phrase matches corresponding to
       phrases within the basic query.
</ul>

  <h3>Composite Query Matching</h3>

<h2>Auxillary Function Details</h2>

<h3>Reportable Phrase Matches</h3>

<ul>
  <li><p>Each phrase in an FTS3 query expression that is not part of an 
       expression descended from the right-hand side of a NOT operator shall 
       be considered a <i>reportable phrase</i>.

  <li><p> All phrase matches corresponding to <i>reportable phrase</i> within
       the current row shall be considered <i>reportable phrase matches</i>
       by the offsets, snippet and matchinfo functions.
</ul>

<h3>Offsets Function</h3>

<ul>
  <li><p>
    The offsets function shall return a text value consisting of <i>N</i>
    integers separated by space characters, where <i>N</i> is a multiple of
    four greater than zero.

  <li><p>
    For each token in each <i>reportable phrase match</i> that occurs within 
    the current row, the return value of the offsets function shall include a 
    set of four integer values, as follows:

     <ul>
       <li> The column number of the FTS3 table column in which the
            <i>reportable phrase match</i> occurs.
       <li> The reportable term number of the corresponding term within the 
            FTS3 query expression.  
       <li> The byte offset of the first byte of the token within the UTF-8 
            representation of the text value stored in the FTS3 table column
            in which the token is found.
       <li> The number of bytes consumed by the token within the UTF-8 
            representation of the text value stored in the FTS3 table column
            in which the token is found.
     </ul>

  <li><p>
    Within the return value of the offsets() function, the sets of four 
    integers shall be sorted in ascending order by column number, then by
    byte offset, then by reportable term number.
</ul>

<h3>Snippet Function</h3>

<h3>Matchinfo Function</h3>

  <ul>
    <li><p>
        The return value of the matchinfo function shall be a blob value
         containing an array of (2 + 3*<i>R</i>*<i>C</i>) unsigned 32-bit
         integers, where <i>R</i> is the number of <i>reportable phrases</i>
         in the query and <i>C</i> is the number of user-defined columns in 
         the FTS3 table being queried.

    <li><p>
        The first 32-bit unsigned integer in the array returned by the 
         matchinfo function shall contain the total number of <i>reportable
         phrases</i> in the FTS3 query.

    <li><p>
        The second 32-bit unsigned integer in the array returned by the
         matchinfo function shall contain the number of user defined columns in
         the FTS3 table, formatted as a 32-bit unsigned integer in machine
         byte-order.

    <li><p>
        For each reportable phrase <i>r</i> and each FTS3 table column 
         <i>c</i>, integer (2 + <i>r</i>*<i>C</i>*3) shall contain the number 
         of reportable phrase matches corresponding to phrase <i>r</i> that 
         appear in column <i>c</i> of the current row.

    <li><p>
        For each reportable phrase <i>r</i> and each FTS3 table column 
         <i>c</i>, integer (2 + <i>r</i>*<i>C</i>*3 + 1) shall contain the
         number of reportable phrase matches corresponding to phrase <i>r</i>
         that appear in column <i>c</i> of all rows in the fts3 table.

    <li><p>
        For each reportable phrase <i>r</i> and each FTS3 table column 
         <i>c</i>, integer (2 + <i>r</i>*<i>C</i>*3 + 2) shall contain the
         number of fts3 table rows for which column <i>c</i> contains one or
         more reportable phrase matches corresponding to reportable phrase
         <i>r</i>.
  </ul>


</ul>


